package cn.fu.ssh.web.action;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.struts2.ServletActionContext;

import cn.fu.ssh.domain.Employee;
import cn.fu.ssh.domain.LeaveBill;
import cn.fu.ssh.service.ILeaveBillService;
import cn.fu.ssh.service.IWorkflowService;
import cn.fu.ssh.utils.SessionContext;
import cn.fu.ssh.utils.ValueContext;
import cn.fu.ssh.web.form.WorkflowBean;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

@SuppressWarnings("serial")
public class WorkflowAction extends ActionSupport implements ModelDriven<WorkflowBean> {

	private WorkflowBean workflowBean = new WorkflowBean();
	
	public WorkflowBean getModel() {
		return workflowBean;
	}
	
	private IWorkflowService workflowService;
	
	private ILeaveBillService leaveBillService;

	public void setLeaveBillService(ILeaveBillService leaveBillService) {
		this.leaveBillService = leaveBillService;
	}

	public void setWorkflowService(IWorkflowService workflowService) {
		this.workflowService = workflowService;
	}

	/**
	 * 部署管理首页显示
	 * @return
	 */
	public String deployHome(){
		//1：查询部署对象表，返回List<Deployment>
		List<Deployment> deploymentList = workflowService.findDeploymentList();
		//2：查询流程定义表，返回List<ProcessDefinition>
		List<ProcessDefinition> pdList = workflowService.findProcessDefinitionList();
		//将查询的对象放置到Context上下文对象中
		ValueContext.putValueContext("deploymentList", deploymentList);
		ValueContext.putValueContext("pdList", pdList);
		return "deployHome";
	}
	
	/**
	 * 发布流程(zip)
	 * @return
	 */
	public String newdeploy(){
		//1：获取页面传递的流程名称和流程文件（File类型）
		//流程名称
		String filename = workflowBean.getFilename();
		//流程文件（File类型）
		File file = workflowBean.getFile();
		//完成部署
		workflowService.saveDeployment(filename,file);
		return "list";
	}
	
	/**
	 * 删除部署信息
	 */
	public String delDeployment(){
		//获取部署对象ID
		String deploymentId = workflowBean.getDeploymentId();
		//使用部署对象ID，删除流程定义（级联删除）
		workflowService.deleteDeploymentByID(deploymentId);
		return "list";
	}
	
	/**
	 * 查看流程图
	 * @throws Exception 
	 */
	public String viewImage() throws Exception{
		//1：获取资源图片名称和部署ID
		//资源图片名称
		String imageName = workflowBean.getImageName();
		//部署ID
		String deploymentId = workflowBean.getDeploymentId();
		//2：使用资源图片名称和部署ID，查询资源文件表，获取存放图片的输入流InputStream
		InputStream in = workflowService.findInputStreamByImageNameAndDeploymentId(imageName,deploymentId);
		//3：将InputStream的输入流，写到输出流中
		//获取输出流
		HttpServletResponse response = ServletActionContext.getResponse();
		OutputStream out =response.getOutputStream();
		for(int b=-1;(b=in.read())!=-1;){
			out.write(b);
		}
		out.close();
		in.close();
		return null;
	}
	
	// 启动流程
	public String startProcess(){
		//获取请假单ID
		Long id = workflowBean.getId();
		//启动流程实例，并设置请假单的状态
		workflowService.saveStartProcessInstance(id);
		return "listTask";
	}
	
	
	
	/**
	 * 任务管理首页显示
	 * @return
	 */
	public String listTask(){
		//1：从Session中获取当前用户信息，获取任务的办理人
		Employee employee = SessionContext.get();
		//获取任务的办理人
		String name = employee.getName();
		//2：使用任务的办理人，查询任务表，指定个人任务，返回List<Task>
		List<Task> taskList = workflowService.findTasklistByUser(name);
		ValueContext.putValueContext("taskList", taskList);
		return "task";
	}
	
	/**
	 * 打开任务表单
	 */
	public String viewTaskForm(){
		//获取任务id
		String taskId = workflowBean.getTaskId();
		//1：使用任务ID，查询流程图中当前任务的FormKey
		TaskFormData taskFormData = workflowService.findTaskFormData(taskId);
		//获取FormKey
		String formKey = taskFormData.getFormKey();//（workflowAction_audit.action）
		//查询请假单ID
		String objId = workflowService.findObjIdByTaskId(taskId);
		//2：同时传递2个参数请假申请表单ID和任务ID
		formKey = formKey+"?taskId="+taskId+"&id="+objId;
		//3：将workflowAction_audit.action值放置到context对象中，使用struts2完成重定向到audit方法
		ValueContext.putValueContext("formKey", formKey);
		return "viewTaskForm";
	}
	
	// 准备表单数据
	public String audit(){
		//1：使用请假申请ID，查询请假申请对象LeaveBill，放置到栈顶，进行表单回显
		Long id = workflowBean.getId();
		if(id!=null){
			LeaveBill leaveBill = leaveBillService.findLeaveBillByID(id);
			//放置到栈顶
			ValueContext.putValueStack(leaveBill);
		}
		//获取任务ID
		String taskId = workflowBean.getTaskId();
		//2:使用任务ID，获取当前任务连线的名称，将连线的名称放置到List<String>
		List<String> outcomeList = workflowService.findOutcomeNameListByTaskId(taskId);
		ValueContext.putValueContext("outcomeList", outcomeList);
		//3：使用任务ID，查询每个任务提交的批注（目的：用来查询领导者的审核信息）
		List<Comment> commentList = workflowService.findCommentListByTaskId(taskId);
		ValueContext.putValueContext("commentList", commentList);
		return "taskForm";
	}
	
	/**
	 * 提交任务
	 */
	public String submitTask(){
		workflowService.saveSubmitTask(workflowBean);
		return "listTask";
	}
	
	/**
	 * 查看当前流程图（查看当前活动节点，并使用红色的框标注）
	 */
	public String viewCurrentImage(){
		//1：查看流程图：
		//获取任务ID
		String taskId = workflowBean.getTaskId();
		//获取流程定义对象
		ProcessDefinition pd = workflowService.findProcessDefinitionByTaskId(taskId);
		//（4）获取部署ID和资源图片名称
		String deployementId = pd.getDeploymentId();
		String resouceName = pd.getDiagramResourceName();
		ValueContext.putValueContext("deploymentId", deployementId);
		ValueContext.putValueContext("imageName", resouceName);
		//2：动态使用红色框，显示正在执行的流程，查询坐标，将坐标返回Map<String,Object>
		Map<String, Object> map = workflowService.findCoordingByTaskId(taskId);
		ValueContext.putValueContext("acs", map);
		return "image";
	}
	
	// 查看历史的批注信息
	public String viewHisComment(){
		//1：使用请假单ID，查询请假的申请信息，放置到栈顶，实现表单回显
		Long id = workflowBean.getId();
		if(id!=null){
			LeaveBill leaveBill = leaveBillService.findLeaveBillByID(id);
			//放置到栈顶
			ValueContext.putValueStack(leaveBill);
		}
		//2：使用请假单ID，查询每个任务提交的批注（目的：用来查询领导者的审核信息）
		List<Comment> commentList = workflowService.findCommentListById(id);
		ValueContext.putValueContext("commentList", commentList);
		return "viewHisComment";
	}
}
